// Tags:
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <queue>
#define a(x, y) (((x - 1) * m + y) << 1)
#define b(x, y) ((((x - 1) * m + y) << 1) - 1)

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

const int N = 1e4 + 5, inf = 0x3f3f3f3f;
int n, m, s, t, map[N][N], cnt, ans;
int e_cnt = 1, heads[N], d[N];
std::queue<int> q;

struct Edge {
  int v, nxt, f;
} e[N << 1];

inline void add(int u, int v, int w) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].f = w;
  e[++e_cnt].v = u, e[e_cnt].nxt = heads[v], heads[v] = e_cnt, e[e_cnt].f = 0;
}

inline bool bfs() {
  memset(d, 0, sizeof(d));
  while (!q.empty()) q.pop();
  q.push(s);
  d[s] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = heads[u], v; i; i = e[i].nxt) {
      if (!d[v = e[i].v] && e[i].f) {
        d[v] = d[u] + 1;
        if (v == t) return true;
        q.push(v);
      }
    }
  }
  return false;
}

int dinic(int u, int flow) {
  if (u == t) return flow;
  int rest = flow, k;
  for (int i = heads[u], v; i && rest; i = e[i].nxt) {
    if (d[v = e[i].v] == d[u] + 1 && e[i].f) {
      k = dinic(v, std::min(rest, e[i].f));
      if (!k) d[v] = 0;
      e[i].f -= k;
      e[i ^ 1].f += k;
      rest -= k;
    }
  }
  return flow - rest;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("missile.in", "r", stdin);
  freopen("missile.out", "w", stdout);
#endif
#endif

  read(n), read(m);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) read(map[i][j]), add(a(i, j), b(i, j), inf);
  }
  s = 0, t = (n * m << 1) + 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      int max = 0;
      if (map[i][j] == -1) {
        add(0, a(i, j), inf);
        for (int k = i; k; --k) max = std::max(max, map[k][j]);
        for (int k = i; k > 1; --k)
          add(a(k, j), a(k - 1, j), max - std::max(0, map[k][j]));
      }
      if (map[i][j] == -2) {
        add(0, a(i, j), inf);
        for (int k = i; k <= n; ++k) max = std::max(max, map[k][j]);
        for (int k = i; k < n; ++k)
          add(a(k, j), a(k + 1, j), max - std::max(0, map[k][j]));
      }
      if (map[i][j] == -3) {
        add(b(i, j), t, inf);
        for (int k = j; k; --k) max = std::max(max, map[i][k]);
        for (int k = j; k > 1; --k)
          add(b(i, k - 1), b(i, k), max - std::max(0, map[i][k]));
      }
      if (map[i][j] == -4) {
        add(b(i, j), t, inf);
        for (int k = j; k <= m; ++k) max = std::max(max, map[i][k]);
        for (int k = j; k < m; ++k)
          add(b(i, k + 1), b(i, k), max - std::max(0, map[i][k]));
      }
      ans += max;
    }
  }
  int flow;
  while (bfs()) {
    if ((flow = dinic(s, inf)) != 0) ans -= flow;
  }
  printf("%d", ans);
  return 0;
}